package jmine.tec.report.impl.table;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import jmine.tec.report.api.table.ReportCell;
import jmine.tec.report.api.table.ReportColumn;
import jmine.tec.report.api.table.ReportRow;
import jmine.tec.report.api.table.ReportTable;
import jmine.tec.report.api.table.ReportTableGroup;
import jmine.tec.report.impl.AbstractReportElement;

/**
 * @author adalberto.kishi
 * @param <V>
 */
public class ReportTableInfoRowImpl<V> extends AbstractReportElement implements ReportTable<V>, Serializable {

    public static final String RENDERER = "tableInfoRowReport";

    private List<ReportColumn<V>> columns;

    private List<ReportCell> tableHeader;

    private List<ReportTableGroup<V>> groups;

    private Iterable<V> records;

    private boolean hasHeader;

    private boolean hasFooter;

    /**
     * Construtor
     * 
     * @param id id
     */
    public ReportTableInfoRowImpl(String id) {
        super(id);
        this.columns = new LinkedList<ReportColumn<V>>();
        this.tableHeader = new LinkedList<ReportCell>();
        this.groups = new LinkedList<ReportTableGroup<V>>();
        this.hasHeader = true;
        this.hasFooter = false;
    }

    /**
     * {@inheritDoc}
     */
    public void setRecords(Iterable<V> records) {
        this.records = records;
    }

    /**
     * {@inheritDoc}
     */
    public void addColumn(ReportColumn<V> column) {
        column.getParameters().setParent(this.getParameters());
        this.columns.add(column);
    }

    /**
     * {@inheritDoc}
     */
    public Iterator<ReportRow<V>> createRowIterator() {
        if (this.records == null || this.columns.isEmpty()) {
            List<ReportRow<V>> emp = Collections.emptyList();
            return emp.iterator();
        } else {
            return new TableRowIterator<V>(this.records.iterator(), this.columns, this.groups);
        }
    }

    /**
     * {@inheritDoc}
     */
    public List<ReportColumn<V>> getColumns() {
        return Collections.unmodifiableList(this.columns);
    }

    /**
     * {@inheritDoc}
     */
    public String getRendererType() {
        return RENDERER;
    }

    /**
     * {@inheritDoc}
     */
    public ReportRow createContentFooter() {
        Map<String, ReportCell> cells = new HashMap<String, ReportCell>();
        for (ReportColumn<?> column : this.getColumns()) {
            cells.put(column.getId(), column.getFooter());
        }
        return new ReportRowImpl<V>(cells);
    }

    /**
     * {@inheritDoc}
     */
    public ReportRow createContentHeader() {
        Map<String, ReportCell> cells = new HashMap<String, ReportCell>();
        for (ReportColumn<?> column : this.getColumns()) {
            cells.put(column.getId(), column.getHeader());
        }
        return new ReportRowImpl<V>(cells);
    }

    /**
     * {@inheritDoc}
     */
    public boolean hasContentFooter() {
        return this.hasFooter;
    }

    /**
     * {@inheritDoc}
     */
    public boolean hasContentHeader() {
        return this.hasHeader;
    }

    /**
     * @param hasHeader the hasHeader to set
     */
    public void setHasHeader(boolean hasHeader) {
        this.hasHeader = hasHeader;
    }

    /**
     * @param hasFooter the hasFooter to set
     */
    public void setHasFooter(boolean hasFooter) {
        this.hasFooter = hasFooter;
    }

    /**
     * {@inheritDoc}
     */
    public void addTableHeader(ReportCell cell) {
        cell.getParameters().setParent(this.getParameters());
        this.tableHeader.add(cell);
    }

    /**
     * {@inheritDoc}
     */
    public void addGroup(ReportTableGroup<V> group) {
        group.getParameters().setParent(this.getParameters());
        this.groups.add(group);
    }

    /**
     * {@inheritDoc}
     */
    public List<ReportCell> getTableHeader() {
        return Collections.unmodifiableList(this.tableHeader);
    }

    /**
     * {@inheritDoc}
     */
    public List<ReportTableGroup<V>> getTableGroup() {
        return this.groups;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isOrdemReversa() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public void setOrdemReversa(boolean ordemReversa) {
        // Não faz nada
    }

}
